/*
 * Chastoslov
 * Copyright (C) 2009 Alexandr Stroghov
 * 
 * stroghov@gmail.com
 * 
 * This program is free software; you can redistribute it and/or modify it under the terms of the 
 * GNU General Public License, version 2, as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this program; if 
 * not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
 * MA 02111-1307 USA
*/

package world.ah.wf.guiclient;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Arrays;
import java.util.Properties;
import javax.swing.JComboBox;
import javax.swing.UIManager;
import java.nio.charset.Charset;
//import org.apache.commons.codec.binary.Base64;

/**
 * Сборник подпрограмм общего назначения 
 */
public class General {
  public static OptionsHolder optionsHolder;
  private static Properties langProp = null;
  private static String languageCode = "";
  private static String defaultCharset = null;
  /**
   * Возвращает код (название по-английски) текущего языка 
   * @return код текущего языка 
   */
  public static String getLanguageCode() {return languageCode;}
  /**
   * Загружает файл языка и устанавливает необходимое окружение для отображения интерфейса 
   * на данном языке
   * @param languageFileName имя файла языка
   */
  public static void loadLanguageFile(String languageFileName) throws Exception {
    langProp = null;
    languageCode = "";
    if(languageFileName != null && languageFileName.length() > 0) {
      Properties prop = new Properties();
      prop.load(new FileInputStream(languageFileName));
      langProp = prop;
      languageCode = prop.getProperty("languageCode", "");
    } 
    
    System.out.println("Файл языка: " + languageFileName + "; Код языка: " + languageCode);
    
  }
  /**
   * Заполняет список текстов
   * @param list Список текстов
   * @param conn Соединение с БД
   * @throws java.lang.Exception
   */
  public static void fillTextList(JComboBox list, Connection conn) throws Exception { 
    Statement st = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
          ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);
    ResultSet rs = st.executeQuery("select ID, TITLE from TEXT order by 2 asc");
    list.removeAllItems();
    while(rs.next()) {
      list.addItem(new KeyedItem(rs.getInt(1), rs.getString(2)));
    };
    rs.close();
    list.setSelectedIndex(-1);
  }
  /**
   * Центрирует форму относительно экрана
   * @param frame центрируемая форма
   */
  public static void centerFrame(Window frame) {
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = frame.getSize();
    if (frameSize.height > screenSize.height) frameSize.height = screenSize.height;
    if (frameSize.width > screenSize.width) frameSize.width = screenSize.width;
    frame.setLocation((screenSize.width - frameSize.width) / 2, 
                      (screenSize.height - frameSize.height) / 2
                     );
  }
  /**
   * Возвращает окну минимальные размеры, если ее текущие размеры оказываются менее заданных
   * минимальных размеров.
   * @param window окно
   * @param width минимальная ширина
   * @param height минимальная высота
   */
  public static void controlMinimumSize(Window window, int width, int height) {
    Rectangle rect = window.getBounds();
    boolean change = false; 
    if(window.getWidth() < width) {rect.setSize(width, window.getHeight()); change = true;}
    if(window.getHeight() < height) {rect.setSize(window.getWidth(), height); change = true;}
    if(change) window.setBounds(rect);
  }
  /**
   * Шифрует незашифрованный или расшифровывает зашифрованный массив байтов.
   * @param array массив байтов
   */
  public static void cryptByteArray(byte[] array) {
    long g = 23;
    for(int i = 0; i < array.length; i++) {
      g = (71365 * g + 17) % 200023; 
      array[i] ^= (byte)g;
    }
  }
  /**
   * Возвращает исходный массив символов в зашифрованном виде.
   * @param array исходный массив символов
   * @return массив символов в зашифрованном виде
   */
  public static char[] encryptCharArray(char[] array) {
    byte[] b = new byte[array.length * 2];
    for(int i = 0; i < array.length; i++) {
      b[i * 2] = (byte)(array[i] >>> 8);
      b[i * 2 + 1] = (byte)(array[i] & 0x00FF);
    }
    cryptByteArray(b);
    //byte[] b64 = Base64.encodeBase64(b);
    byte[] b64 = b;
    char[] result = new char[b64.length];
    for(int i = 0; i < result.length; i++) result[i] = (char)b64[i];
    return result;
  }
  /**
   * Возвращает исходный массив символов в расшифрованном виде.
   * @param array исходный массив символов
   * @return массив символов в расшифрованном виде
   */
  public static char[] decryptCharArray(char[] array) {
    byte[] b64 = new byte[array.length];
    for(int i = 0; i < b64.length; i++) b64[i] = (byte)array[i];
    //byte[] b = Base64.decodeBase64(b64);
    byte[] b = b64;
    cryptByteArray(b);
    char[] result = new char[b.length / 2];
    for(int i = 1; i < b.length; i += 2) result[(i - 1) / 2] = (char)((b[i - 1] << 8) + b[i]);
    Arrays.fill(b, (byte)0);
    return result;
  }
  /**
   * Возвращает текстовый элемент (перевод) на установленном в программе текущем языке
   * @param name имя элемента
   * @param ifNotFound возвращаемый текст, если перевод не найден 
   * @return перевод
   */
  public static String getLangItem(String name, String ifNotFound) {
    if(langProp == null) return ifNotFound;
    return langProp.getProperty(name, ifNotFound);
  } 
  //
  /**
   * Возвращает текстовый элемент (перевод) на установленном в программе текущем языке
   * @param name имя элемента
   * @return перевод
   */
  public static String getLangItem(String name) {return getLangItem(name, "");} 

  //
  public static void setLookAndFeelFromOptions() { 
    try { 
      if(optionsHolder.getLookAndFeelUsageKind() == OptionsHolder.LOOK_AND_FEEL_USE_SYSTEM)    
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      else if(optionsHolder.getLookAndFeelUsageKind() == OptionsHolder.LOOK_AND_FEEL_USE_CUSTOM)
        UIManager.setLookAndFeel(optionsHolder.getLookAndFeelClassName());
      else UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
    } catch(Exception ex) {optionsHolder.setLookAndFeelUsageKind(0); ex.printStackTrace();}
  }
  //
  public static String getDefaultCharset() {
    // In Windows 8 (English USA version) this method gave windows-1252 instead of windows-1251
    // In Windows XP (Russian version) this method gave windows-1251
    return Charset.defaultCharset().name();
    //return "UTF-16";
  }
  //
  
}





